﻿<?xml version="1.0" encoding="utf-8" ?>

<scope
	xmlns="http://metalx.org/Program"
	xmlns:cpu16="http://metalx.org/Intel/80286/Operators"
	xmlns:cpu32="http://metalx.org/Intel/80386/Operators"
	xmlns:op16="http://metalx.org/Intel/80286/Operands"
	xmlns:op32="http://metalx.org/Intel/80386/Operands"
	xmlns:ex16="http://metalx.org/Intel/80286/ExtendedOperators"
	xmlns:ex32="http://metalx.org/Intel/80386/ExtendedOperators"
	xmlns:math16="http://metalx.org/Intel/80286/Math"
	xmlns:math32="http://metalx.org/Intel/80386/Math"
	xmlns:seg16="http://metalx.org/Intel/80286/Segments"
	xmlns:seg32="http://metalx.org/Intel/80386/Segments"
	xmlns:imm32="http://metalx.org/Intel/80386/Immediate"
	xmlns:ctrl16="http://metalx.org/Intel/80286/Control"
	xmlns:gdt16="http://metalx.org/Intel/80286/DescriptorTable"
	xmlns:gdt32="http://metalx.org/Intel/80386/DescriptorTable"
	xmlns:sys="http://metalx.org/Pc/Bios/System"
	xmlns:bios="http://metalx.org/Pc/Bios/Functions"
	xmlns:logic32="http://metalx.org/Intel/80386/Logic"
	xmlns:index32="http://metalx.org/Intel/80386/Index"
	xmlns:pic="http://metalx.org/Pc/Pic/Ports"
	xmlns:cmd="http://metalx.org/Pc/Pic/Commands"
	xmlns:dsk="http://metalx.org/i286/Functions/Disk"
	xmlns:hd="http://metalx.org/i386/Functions/HardDrive"
	xmlns:imm16="http://metalx.org/Intel/80286/Immediate"
	xmlns:inc16="http://metalx.org/Intel/80286/Increment"
	xmlns:inc32="http://metalx.org/Intel/80386/Increment"
	xmlns:hex32="http://metalx.org/i386/Functions/Hexadecimal"
	xmlns:con="http://metalx.org/i286/Functions/Console">

	<!--Set CPU To Known State-->
	<cpu16:ClearDirectionFlag/>

	<cpu16:CopyImmediateToAX/>
	<hex>0000</hex>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:SS-AXRegister/>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:DS-AXRegister/>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:ES-AXRegister/>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:FS-AXRegister/>

	<cpu16:CopyOperandToSegmentRegister16/>
	<seg16:GS-AXRegister/>

	<cpu16:CopyRegisterToOperand16/>
	<op16:AX-SPRegister/>

	<cpu16:JumpToImmediatePointer16/>
	<addressOf ref="start" type="Pointer16"/>

	<label id="start"/>

	<!--Enable A20 Gate-->
	<cpu16:CopyImmediateToAX/>
	<sys:EnableA20Gate/>

	<cpu16:CallImmediate8Interrupt/>
	<bios:SystemFunctions/>

	<!--Get Memory Map-->
	<cpu16:Operand32/>
	<cpu16:CopyImmediateToDI/>
	<hex>00003000</hex>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToBX/>
	<int>0</int>

	<label id="nextEntry"/>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToAX/>
	<hex>0000e820</hex>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToDX/>
	<string>PAMS</string>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToCX/>
	<int>24</int>

	<cpu16:CallImmediate8Interrupt/>
	<bios:SystemFunctions/>

	<cpu16:MathImmediate8ToOperand16Function/>
	<math16:AddToDIRegister/>
	<byte>24</byte>

	<cpu16:BranchToRelativeIfCarry8/>
	<addressOf ref="done" type="Relative8"/>

	<cpu16:MathImmediateToOperandFunction16/>
	<math16:CompareWithBXRegister/>
	<hex>0000</hex>

	<cpu16:BranchToRelativeIfEqual8/>
	<addressOf ref="done" type="Relative8"/>

	<cpu16:JumpToRelative8/>
	<addressOf ref="nextEntry" type="Relative8"/>

	<label id="done"/>

	<cpu16:Operand32/>
	<cpu16:CopyImmediateToOperandFunction16/>
	<imm16:CopyImmediateToDIAddress/>
	<hex>ffffffff</hex>

	<!--Disable NMI-->
	<cpu16:ReadFromImmediate8PortToAL/>
	<hex>70</hex>

	<cpu16:OrALWithImmediate/>
	<binary>10000000</binary>

	<cpu16:WriteALToImmediate8Port/>
	<hex>70</hex>

	<!--Load Global Descriptor Table-->
	<cpu16:ClearInterruptFlag/>

	<cpu16:ExtendedOperator/>
	<ex16:DescriptorTableFunction/>
	<gdt16:CopyImmediate16AddressToGlobalDescriptorTableRegister/>
	<addressOf ref="globalDescriptorTablePointer" type="Absolute16"/>

	<!--Switch To 32-Bit Protected Mode-->
	<cpu16:ExtendedOperator/>
	<ex16:CopyControlRegisterToRegister/>
	<ctrl16:AX-ControlRegister0/>

	<cpu16:OrALWithImmediate/>
	<binary>00000001</binary>

	<cpu16:ExtendedOperator/>
	<ex16:CopyRegisterToControlRegister/>
	<ctrl16:AX-ControlRegister0/>

	<!--Jump to segment-->
	<cpu16:JumpToImmediatePointer16/>
	<addressOf ref="enterProtectedMode" type="Absolute16"/>
	<hex>0008</hex>
	
	<!--32-bit Protected Mode-->
	<label id="enterProtectedMode"/>

	<!--Setup Segment Registers-->
	<cpu32:CopyImmediateToAX/>
	<hex>00000010</hex>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:SS-AXRegister/>

	<cpu32:CopyImmediateToSP/>
	<hex>00010000</hex>
	
	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:DS-AXRegister/>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:ES-AXRegister/>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:FS-AXRegister/>

	<cpu32:CopyOperandToSegmentRegister/>
	<seg32:GS-AXRegister/>
	
	<!--Enable NMI-->
	<cpu32:ReadFromImmediate8PortToAL/>
	<hex>70</hex>

	<cpu32:AndALWithImmediate/>
	<binary>01111111</binary>

	<cpu32:WriteALToImmediate8Port/>
	<hex>70</hex>

	<!--Reprogram Master Interrupt Controller-->
	<cpu32:CopyImmediateToAL/>
	<cmd:InitializeForEnvironment/>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterCommand/>

	<cpu32:CopyImmediateToAL/>
	<byte>32</byte>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterData/>

	<cpu32:CopyImmediateToAL/>
	<binary>00000100</binary>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterData/>

	<cpu32:CopyImmediateToAL/>
	<cmd:Environment8086Mode/>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterData/>

	<cpu32:CopyImmediateToAL/>
	<hex>00</hex>

	<cpu32:WriteALToImmediate8Port/>
	<pic:MasterData/>

	<!--Reprogram Slave Interrupt Controller-->
	<cpu32:CopyImmediateToAL/>
	<cmd:InitializeForEnvironment/>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveCommand/>

	<cpu32:CopyImmediateToAL/>
	<byte>40</byte>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveData/>

	<cpu32:CopyImmediateToAL/>
	<binary>00000010</binary>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveData/>

	<cpu32:CopyImmediateToAL/>
	<cmd:Environment8086Mode/>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveData/>

	<cpu32:CopyImmediateToAL/>
	<hex>00</hex>

	<cpu32:WriteALToImmediate8Port/>
	<pic:SlaveData/>

	<!--Read Disk Information From Hard Drive-->
	<cpu32:CopyImmediateToDI/>
	<hex>00010000</hex>

	<cpu32:CopyImmediateToAX/>
	<int>1</int>

	<cpu32:CopyImmediateToBX/>
	<int>0</int>

	<cpu32:CopyImmediateToCX/>
	<int>1</int>

	<cpu32:CopyImmediateToDX/>
	<hex>00000170</hex>

	<cpu32:CallRelative/>
	<addressOf ref="readBlocks" type="Relative32"/>

	<cpu32:CopyOperandToRegister/>
	<op32:AX-DIAddressPlusImmediate8/>
	<byte>16</byte>

	<cpu32:CopyOperandToRegister/>
	<op32:CX-DIAddressPlusImmediate8/>
	<byte>20</byte>

	<cpu32:LogicFunction/>
	<logic32:PushDIAddressPlusImmediate8/>
	<byte>52</byte>

	<cpu32:CallRelative/>
	<addressOf ref="readBlocks" type="Relative32"/>

	<!--Read Programs From Hard Drive-->
	<cpu32:CopyRegisterToOperand/>
	<op32:DI-SIRegister/>

	<cpu32:CopySIAddressToAXAndIncrementSI/>

	<cpu32:CopyRegisterToOperand/>
	<op32:AX-CXRegister/>

	<label id="forEachProgram"/>

	<cpu32:PushCXToStack/>

	<cpu32:CopySIAddressToAXAndIncrementSI/>

	<cpu32:PushAXToStack/>

	<cpu32:CopySIAddressToAXAndIncrementSI/>

	<cpu32:CopyRegisterToOperand/>
	<op32:AX-CXRegister/>

	<cpu32:CopySIAddressToAXAndIncrementSI/>

	<cpu32:CopyRegisterToOperand/>
	<op32:AX-DIRegister/>

	<cpu32:PullAXFromStack/>

	<cpu32:CallRelative/>
	<addressOf ref="readBlocks" type="Relative32"/>

	<cpu32:PullCXFromStack/>

	<cpu32:LoopToRelative8/>
	<addressOf ref="forEachProgram" type="Relative8"/>

	<!--Restore Start Address-->
	<cpu32:PullSIFromStack/>

	<!--<cpu32:SetInterruptFlag/>

	<cpu32:LogicFunction/>
	<logic32:JumpToSIRegister/>-->

	<cpu32:JumpToImmediatePointer/>
	<hex>00009c00</hex>
	<hex>0008</hex>

	<!--Global Descriptor Table Pointer-->
	<label id="globalDescriptorTablePointer"/>
	<hex>0017</hex>
	<addressOf ref="globalDescriptorTable" type="Absolute16"/>

	<!--Global Descriptor Table-->
	<label id="globalDescriptorTable"/>
	<!--Null Descriptor (0000)-->

	<!--Size-->
	<hex>0000</hex>
	<!--Base (Low)-->
	<hex>0000</hex>
	<!--Base (Mid)-->
	<hex>00</hex>
	<!--Access-->
	<binary>00000000</binary>
	<!--Flags / Size (High)-->
	<binary>00000000</binary>
	<!--Base (High)-->
	<hex>00</hex>

	<!--Code Descriptor (0008)-->

	<!--Size-->
	<hex>ffff</hex>
	<!--Base (Low)-->
	<hex>0000</hex>
	<!--Base (Mid)-->
	<hex>00</hex>
	<!--Access-->
	<binary>10011010</binary>
	<!--Flags / Size (High)-->
	<binary>11001111</binary>
	<!--Base (High)-->
	<hex>00</hex>

	<!--Data Descriptor (0010)-->

	<!--Size-->
	<hex>ffff</hex>
	<!--Base (Low)-->
	<hex>0000</hex>
	<!--Base (Mid)-->
	<hex>00</hex>
	<!--Access-->
	<binary>10010010</binary>
	<!--Flags / Size (High)-->
	<binary>11001111</binary>
	<!--Base (High)-->
	<hex>00</hex>

	<!--Functions-->
	<!--<label id="readBlocks"/>

	<cpu32:PushSIToStack/>
	<cpu32:PushDIToStack/>
	<cpu32:PushBXToStack/>

	<hd:ReadBlocks/>

	<cpu32:PullBXFromStack/>
	<cpu32:PullDIFromStack/>
	<cpu32:PullSIFromStack/>

	<cpu32:ReturnToNearCaller/>-->

	<label id="readBlocks"
			xmlns:math32="http://metalx.org/Intel/80386/Math"
			xmlns:shift32="http://metalx.org/Intel/80386/Shift"
			xmlns:pata="http://metalx.org/Pc/Pata/Ports"
			xmlns:status="http://metalx.org/Pc/Pata/Status"
			xmlns:drive="http://metalx.org/Pc/Pata/DriveSelect"
			xmlns:cmd="http://metalx.org/Pc/Pata/Commands">
		<scope>
			<cpu32:PushAllRegistersToStack/>

			<label id="nextBlock"/>

			<cpu32:PushDXToStack/>
			<cpu32:PushCXToStack/>
			<cpu32:PushBXToStack/>
			<cpu32:PushAXToStack/>

			<!--Reset Controller-->
			<!--<cpu32:MathImmediateToOperandFunction/>
			<math32:AddToDXRegister/>
			<hex>00000206</hex>

			<cpu32:CopyImmediateToAL/>
			<binary>00000100</binary>

			<cpu32:WriteALToDXPort/>

			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>

			<cpu32:CopyImmediateToAL/>
			<binary>00000000</binary>

			<cpu32:WriteALToDXPort/>

			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>

			<cpu32:MathImmediateToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<hex>00000206</hex>-->

			<!--Select Drive-->
			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:AddToDXRegister/>
			<pata:DriveAndHead/>

			<!--<cpu32:PushAXToStack/>-->

			<cpu32:ShiftRegisterByImmediate8Function/>
			<shift32:ShiftAXRegisterRight/>
			<byte>24</byte>

			<cpu32:AndALWithImmediate/>
			<binary>00001111</binary>

			<cpu32:OrALWithImmediate/>
			<binary>11100000</binary>

			<cpu32:ShiftRegisterByImmediateFunction8/>
			<shift32:ShiftBLRegisterLeft/>
			<byte>4</byte>

			<cpu32:OrRegisterWithOperand8/>
			<op32:AL-BLRegister/>

			<cpu32:WriteALToDXPort/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<pata:DriveAndHead/>

			<!--Wait For Drive Select-->
			<cpu32:CallRelative/>
			<addressOf ref="sleep" type="Relative32"/>

			<!--Disable DMA-->
			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:AddToDXRegister/>
			<pata:Features/>

			<cpu32:CopyImmediateToAL/>
			<binary>00000000</binary>

			<cpu32:WriteALToDXPort/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<pata:Features/>

			<!--Enable IRQs-->
			<cpu32:Operand16/>
			<cpu32:MathImmediateToOperandFunction/>
			<math32:AddToDXRegister/>
			<hex>0206</hex>

			<cpu32:CopyImmediateToAL/>
			<binary>00000000</binary>

			<cpu32:WriteALToDXPort/>

			<cpu32:Operand16/>
			<cpu32:MathImmediateToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<hex>0206</hex>

			<!--Set Byte Count 0-->
			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:AddToDXRegister/>
			<pata:ByteCount0/>

			<cpu32:CopyImmediateToAL/>
			<hex>00</hex>

			<cpu32:WriteALToDXPort/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<pata:ByteCount0/>

			<!--Set Byte Count 1-->
			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:AddToDXRegister/>
			<pata:ByteCount1/>

			<cpu32:CopyImmediateToAL/>
			<hex>08</hex>

			<cpu32:WriteALToDXPort/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<pata:ByteCount1/>

			<!--Send ATAPI Packet Command-->
			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:AddToDXRegister/>
			<pata:Command/>

			<cpu32:CopyImmediateToAL/>
			<cmd:Packet/>

			<cpu32:WriteALToDXPort/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<pata:Command/>

			<!--Wait While Busy-->
			<cpu32:CallRelative/>
			<addressOf ref="wait" type="Relative32"/>

			<cpu32:CallRelative/>
			<addressOf ref="poll" type="Relative32"/>

			<!--Send ATAPI Packet-->
			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:AddToDXRegister/>
			<pata:Data/>

			<cpu32:Operand16/>
			<cpu32:CopyImmediateToAX/>
			<hex>0028</hex>

			<cpu32:Operand16/>
			<cpu32:WriteAXToDXPort/>

			<!--<cpu32:PullAXFromStack/>-->

			<cpu32:CopyOperandToRegister/>
			<op32:AX-IndexAddress/>
			<index32:SP/>

			<cpu32:ShiftRegisterByImmediate8Function/>
			<shift32:RollAXRegisterRight/>
			<byte>16</byte>

			<cpu32:Operand16/>
			<cpu32:ShiftRegisterByImmediate8Function/>
			<shift32:RollAXRegisterRight/>
			<byte>8</byte>

			<cpu32:Operand16/>
			<cpu32:WriteAXToDXPort/>

			<cpu32:ShiftRegisterByImmediate8Function/>
			<shift32:RollAXRegisterLeft/>
			<byte>16</byte>

			<cpu32:Operand16/>
			<cpu32:ShiftRegisterByImmediate8Function/>
			<shift32:RollAXRegisterRight/>
			<byte>8</byte>

			<cpu32:Operand16/>
			<cpu32:WriteAXToDXPort/>

			<cpu32:Operand16/>
			<cpu32:CopyImmediateToAX/>
			<hex>0000</hex>

			<cpu32:Operand16/>
			<cpu32:WriteAXToDXPort/>

			<cpu32:Operand16/>
			<cpu32:CopyImmediateToAX/>
			<hex>0001</hex>

			<cpu32:Operand16/>
			<cpu32:WriteAXToDXPort/>

			<cpu32:Operand16/>
			<cpu32:CopyImmediateToAX/>
			<hex>0000</hex>

			<cpu32:Operand16/>
			<cpu32:WriteAXToDXPort/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<pata:Data/>

			<!--Wait While Busy-->
			<!--<cpu32:WaitForInterrupt/>
			<cpu32:WaitForInterrupt/>
			<cpu32:WaitForInterrupt/>
			<cpu32:WaitForInterrupt/>-->

			<!--Get Byte Count 0-->
			<!--<cpu32:MathImmediate8ToOperandFunction/>
		<math32:AddToDXRegister/>
		<pata:ByteCount0/>
		
		<cpu32:ReadFromDXPortToAL/>

		<cpu32:MathImmediate8ToOperandFunction/>
		<math32:SubtractFromDXRegister/>
		<pata:ByteCount0/>-->

			<!--Get Byte Count 1-->
			<!--<cpu32:MathImmediate8ToOperandFunction/>
		<math32:AddToDXRegister/>
		<pata:ByteCount1/>

		<cpu32:ReadFromDXPortToAL/>

		<cpu32:MathImmediate8ToOperandFunction/>
		<math32:SubtractFromDXRegister/>
		<pata:ByteCount1/>-->

			<!--<cpu32:CallRelative/>
			<addressOf ref="sleep" type="Relative32"/>-->

			<cpu32:CallRelative/>
			<addressOf ref="wait" type="Relative32"/>

			<!--Read Data-->
			<cpu32:CallRelative/>
			<addressOf ref="poll" type="Relative32"/>

			<cpu32:CopyImmediateToCX/>
			<int>1024</int>

			<cpu32:Operand16/>
			<cpu32:Repeat/>
			<cpu32:ReadFromDXPortToDIAddressAndIncrementDI/>

			<cpu32:PullAXFromStack/>
			<cpu32:PullBXFromStack/>
			<cpu32:PullCXFromStack/>
			<cpu32:PullDXFromStack/>
			
			<cpu32:IncrementAX/>
			
			<cpu32:DecrementCX/>
			
			<cpu32:BranchToRelative8IfZero/>
			<addressOf ref="lastBlock" type="Relative8"/>

			<cpu32:JumpToRelative/>
			<addressOf ref="nextBlock" type="Relative32"/>

			<label id="lastBlock"/>
			
			<cpu32:PullAllRegistersFromStack/>

			<cpu32:ReturnToNearCaller/>

			<label id="sleep"/>

			<cpu32:Operand16/>
			<cpu32:MathImmediateToOperandFunction/>
			<math32:AddToDXRegister/>
			<hex>0206</hex>

			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>
			<cpu32:ReadFromDXPortToAL/>

			<cpu32:Operand16/>
			<cpu32:MathImmediateToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<hex>0206</hex>

			<cpu32:ReturnToNearCaller/>

			<label id="wait"/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:AddToDXRegister/>
			<pata:Status/>

			<label id="whileBusy"/>

			<cpu32:ReadFromDXPortToAL/>

			<cpu32:AndALWithImmediate/>
			<status:Busy/>

			<cpu32:BranchToRelative8IfNotZero/>
			<addressOf ref="whileBusy" type="Relative8"/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<pata:Status/>

			<cpu32:ReturnToNearCaller/>
			
			<label id="poll"/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:AddToDXRegister/>
			<pata:Status/>

			<label id="whileEmpty"/>

			<cpu32:ReadFromDXPortToAL/>

			<cpu32:AndALWithImmediate/>
			<status:DataRequest/>

			<cpu32:BranchToRelative8IfZero/>
			<addressOf ref="whileEmpty" type="Relative8"/>

			<cpu32:MathImmediate8ToOperandFunction/>
			<math32:SubtractFromDXRegister/>
			<pata:Status/>

			<cpu32:ReturnToNearCaller/>
		</scope>
	</label>
</scope>